From: Florian Müllner Date: Thu, 26 Jun 2025 10:07:07 +0000 (+0200) Subject: st/entry: Forward label-actor to internal ClutterText X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~124^2^2~14 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=38a28b9bd4abbdcd096af3685be01eb937923fce;p=gnome-shell.git st/entry: Forward label-actor to internal ClutterText The StWidget:label-actor property is a convenient way of setting up an actor's labelled-by relationship. However on StEntry, it is currently fairly useless because if the entry is focused, the actual keyboard focus will be on the internal ClutterText rather than the entry itself, and orca ignores ancestors in most cases. Address this by tracking the entry's label-actor property, and replicate the labelled-by relationship on the internal ClutterText actor. Part-of: --- diff --git a/src/st/st-entry.c b/src/st/st-entry.c index 8830d6300..83ce19040 100644 --- a/src/st/st-entry.c +++ b/src/st/st-entry.c @@ -122,6 +122,7 @@ G_DECLARE_FINAL_TYPE (StEntryAccessible, StWidgetAccessible) static void update_hint_relation (StEntry *entry); +static void update_label_relation (StEntry *entry); static void st_entry_set_property (GObject *gobject, @@ -516,6 +517,14 @@ st_entry_allocate (ClutterActor *actor, clutter_actor_allocate (priv->entry, &child_box); } +static void +st_entry_label_actor_changed_cb (StEntry *entry, + GParamSpec *pspec, + gpointer user_data G_GNUC_UNUSED) +{ + update_label_relation (entry); +} + static void clutter_text_reactive_changed_cb (ClutterActor *text, GParamSpec *pspec, @@ -1048,6 +1057,9 @@ st_entry_init (StEntry *entry) priv->entry, "reactive", G_BINDING_DEFAULT); + g_signal_connect (entry, "notify::label-actor", + G_CALLBACK (st_entry_label_actor_changed_cb), entry); + g_signal_connect(priv->entry, "notify::reactive", G_CALLBACK (clutter_text_reactive_changed_cb), entry); @@ -1528,6 +1540,7 @@ typedef struct _StEntryAccessible StWidgetAccessible parent; AtkObject *current_hint; + AtkObject *current_label; } StEntryAccessible; G_DEFINE_FINAL_TYPE (StEntryAccessible, st_entry_accessible, ST_TYPE_WIDGET_ACCESSIBLE) @@ -1544,6 +1557,7 @@ st_entry_accessible_dispose (GObject *object) StEntryAccessible *accessible = ST_ENTRY_ACCESSIBLE (object); g_clear_object (&accessible->current_hint); + g_clear_object (&accessible->current_label); G_OBJECT_CLASS (st_entry_accessible_parent_class)->dispose (object); } @@ -1656,3 +1670,43 @@ update_hint_relation (StEntry *entry) accessible); } } + +static void +update_label_relation (StEntry *entry) +{ + StEntryPrivate *priv; + AtkObject *accessible; + StEntryAccessible *entry_accessible; + ClutterActor *label_actor; + + priv = st_entry_get_instance_private (entry); + + accessible = clutter_actor_get_accessible (priv->entry); + entry_accessible = ST_ENTRY_ACCESSIBLE (atk_object_get_parent (accessible)); + + if (entry_accessible->current_label != NULL) + { + atk_object_remove_relationship (accessible, + ATK_RELATION_LABELLED_BY, + entry_accessible->current_label); + atk_object_remove_relationship (entry_accessible->current_label, + ATK_RELATION_LABEL_FOR, + accessible); + g_clear_object (&entry_accessible->current_label); + } + + label_actor = st_widget_get_label_actor (ST_WIDGET (entry)); + + if (label_actor != NULL) + { + g_set_object (&entry_accessible->current_label, + clutter_actor_get_accessible (label_actor)); + + atk_object_add_relationship (accessible, + ATK_RELATION_LABELLED_BY, + entry_accessible->current_label); + atk_object_add_relationship (entry_accessible->current_label, + ATK_RELATION_LABEL_FOR, + accessible); + } +}